//=============================================================================

#ifndef ASKELETON_H
  #define ASKELETON_H

//=============================================================================

#include "aList.h"
#include "aVector.h"
#include "aJoint.h"

//=============================================================================

enum asnRet
{
  FINISH = -128,
  NULLED_PATH,
  CANT_OPEN_SKELETON_FILE,
  NO_SUCH_ANIMATION_FOUNDED,
  NULLED_ANIMATION_NAME,
  COL_BAD_VOLUME_SIZE,
  COL_BAD_SKEL_DATA_POINTER,
  COL_NO_JOINTS_DATA,
  ABS_BAD_SKELETON_DATA_POINTER,
  ABS_BAD_SKELETON_JOINTS_COUNT,
  ABS_BAD_ANIM_DATA_POINTER,
  ABS_NO_SUCH_JOINT_FOR_ANIM,
};

//=============================================================================

class aSkeleton
{
  public:
      inline void asCalculateJoints() {asCalculateJoints(joints.alGetFirstItem());}

    aSkeleton();
      asnRet asLoadSkeleton(const aString& path, unsigned int vCount);
      void asDrawSkeleton(aItem<aJoint>* jnt = 0, bool drawAxis = 0)const;
      bool asAddAnimationToJoint(const aString& jntName, const aString& anmName, float* ptr, unsigned int frames);
      asnRet asPrepareAnimation(const aString& name);
      void asRemoveSkeletonData();
      size_t asGetDataVolume()const;
      asnRet asCollectData(void* data, size_t wholeSize)const;
      asnRet asFixTheBones(char* data, int jCount);
      asnRet asAbsorbAnimations(char* data, aList<aString>& animList);
    ~aSkeleton();
  
  private:
    aItem<aJoint>* asGetJointByName(aItem<aJoint>* jnt, const aString& name)const;
    aItem<aJoint>* asAddJoint(aItem<aJoint>* parent);
    void asCalculatePositionsByBindMatrix(aItem<aJoint>* jnt);
    void asGenerateStaticJointsList(aItem<aJoint>* jnt);
    void asCalculateJoints(aItem<aJoint>* jnt);
    void asResetJointsToBind();
    void asCopyDataToCurrentMatrix();
    void asAddFactorToBindPositions();
    void asPrepareBindValues();

  public:
    aList<aJoint*> pubJoints;

  private:
    aList<aJoint> joints;
    const unsigned int factor;
    unsigned int vertexesCount;
};

//=============================================================================

#endif

//=============================================================================
